package ru.sstu.renju.core;

import java.util.ArrayList;
import java.util.List;

import ru.sstu.renju.core.Row.Direction;

/**
 * <code>RowUtil</code> class contains methods for creating list of
 * {@link Row} objects.
 *
 * @author denis_murashev
 * @since Renju 1.0
 */
public final class RowUtil {

	private RowUtil() {
	}

	/**
	 * Provides short list of rows that can start at given cell.
	 *
	 * @param i    column
	 * @param j    row
	 * @return list of rows
	 */
	public static List<Row> shortList(int i, int j) {
		List<Row> rows = new ArrayList<Row>();
		if (i + Row.SIZE <= Game.SIZE) {
			rows.add(new Row(i, j, Direction.RIGHT));
		}
		if (j + Row.SIZE <= Game.SIZE) {
			rows.add(new Row(i, j, Direction.DOWN));
		}
		if (i + Row.SIZE <= Game.SIZE && j + Row.SIZE <= Game.SIZE) {
			rows.add(new Row(i, j, Direction.DOWN_RIGHT));
		}
		if (i + Row.SIZE <= Game.SIZE && j >= Row.SIZE - 1) {
			rows.add(new Row(i, j, Direction.UP_RIGHT));
		}
		return rows;
	}

	/**
	 * Provides long list of rows that contains given cell.
	 *
	 * @param i    column
	 * @param j    row
	 * @return list of rows
	 */
	public static List<Row> longList(int i, int j) {
		List<Row> rows = new ArrayList<Row>();
		int start = Math.max(0, i - Row.SIZE + 1) - i;
		int end = Math.min(Game.SIZE - Row.SIZE, i) - i;
		for (int k = start; k <= end; k++) {
			rows.add(new Row(i + k, j, Direction.RIGHT));
		}
		start = Math.max(0, j - Row.SIZE + 1) - j;
		end = Math.min(Game.SIZE - Row.SIZE, j) - j;
		for (int k = start; k <= end; k++) {
			rows.add(new Row(i, j + k, Direction.DOWN));
		}
		start = Math.max(Math.max(0, i - Row.SIZE + 1) - i,
				Math.max(0, j - Row.SIZE + 1) - j);
		end = Math.min(Math.min(Game.SIZE - Row.SIZE, i) - i,
				Math.min(Game.SIZE - Row.SIZE, j) - j);
		for (int k = start; k <= end; k++) {
			rows.add(new Row(i + k, j + k, Direction.DOWN_RIGHT));
		}
		start = Math.max(Math.max(0, i - Row.SIZE + 1) - i,
				j - Math.min(Game.SIZE - 1, j + Row.SIZE - 1));
		end = Math.min(Math.min(Game.SIZE - Row.SIZE, i) - i,
				j - Math.max(Row.SIZE - 1, j));
		for (int k = start; k <= end; k++) {
			rows.add(new Row(i + k, j - k, Direction.UP_RIGHT));
		}
		return rows;
	}
}
